package cinvestav.adviseme.databasemodel;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import cinvestav.adviseme.datamodel.Foto;
import cinvestav.adviseme.datamodel.Lugar;
import cinvestav.adviseme.datamodel.LugarAgregado;
import cinvestav.adviseme.datamodel.Persona;
import cinvestav.adviseme.datamodel.TipoLugar;
import cinvestav.adviseme.util.DBException;
import cinvestav.adviseme.util.DataBaseDictionary;

public class LugarAgregadoDB extends DataBase implements ILugarAgregadoDB{

	private static Logger log = Logger.getLogger(LugarAgregadoDB.class.getName());
	/**
	 * Constructor vacio
	 * @throws DBException
	 */
	public LugarAgregadoDB() throws DBException {
		super();
		// TODO Auto-generated constructor stub
	}

	@Override
	public List<LugarAgregado> getAll() throws DBException {
		// TODO Auto-generated method stub				
		return null;
	}

	@Override
	public List<LugarAgregado> getByFiter(Map<String, String[]> filtros)
			throws DBException {
		// TODO Auto-generated method stub
		try {

			// Establece la conexion
			Connection c = this.getConnection();
			// Prepara cadena a ejecutar
			PreparedStatement ps = genPreparedStatementeString(filtros, c);
			// Ejecuta consulta
			ResultSet res = this.ejecutarQuery(ps);

			List<LugarAgregado> lugaresAgregados = new LinkedList<LugarAgregado>();

			while (res.next()) {
				LugarAgregado lugarAgregado = new LugarAgregado();
				Persona persona = new Persona();
				Lugar lugar = new Lugar();
				TipoLugar tipoLugar = new TipoLugar();
				
				lugarAgregado.setId(res.getInt("ide_plu"));
				lugarAgregado.setFecha(res.getDate("fec_plu").toString());
				
				persona.setId(res.getInt("ide_per"));
				persona.setNombrePersona(res.getString("nom_per"));
				persona.setApellidoPaterno("app_per");
				persona.setApellidoMaterno("apm_per");
				lugarAgregado.setPersona(persona);
				
				lugar.setId(res.getInt("ide_lug"));
				lugar.setNombre(res.getString("nom_lug"));
				lugar.setDescripcion(res.getString("des_lug"));
				lugar.setLatitud(res.getDouble("lat_lug"));
				lugar.setLongitud(res.getDouble("lon_lug"));
				lugar.setRanking(res.getInt("ran_lug"));
				
				tipoLugar.setId(res.getInt("ide_tip"));
				tipoLugar.setDescripcion(res.getString("des_tip"));				
				lugar.setTipo(tipoLugar);
				
				lugar.setUrlPrincipal(res.getString("fot_lug"));
				
				lugarAgregado.setLugar(lugar);
				
				lugaresAgregados.add(lugarAgregado);
			}
			return lugaresAgregados;
		} catch (SQLException e) {
			// TODO: handle exception
			log.log(Level.SEVERE,
					null, e);
			throw new DBException("Error al ejecutar la consulta:\n"
					+ e.getMessage());
		} catch (DBException e) {
			throw new DBException(e);
		}		
	}
	
	private PreparedStatement genPreparedStatementeString(
			Map<String, String[]> filtros, Connection c) {
		String statement = DataBaseDictionary.GET_BASE_PERSONALUGAR;			

		Boolean ini = Boolean.TRUE;

		for (Map.Entry<String, String[]> entry : filtros.entrySet()) {
			if (ini) {
				statement += " " + entry.getValue()[2] + "." + entry.getKey();
				ini = Boolean.FALSE;
			} else {
				statement += " AND " + entry.getValue()[2] + "." + entry.getKey();
			}
		}

		log.log(Level.SEVERE,null,statement);
		try {
			PreparedStatement ps = c.prepareStatement(statement);
			int cont = 1;

			for (Map.Entry<String, String[]> entry : filtros.entrySet()) {
				String[] val = entry.getValue();
				if (val[1].compareTo(DataBaseDictionary.STRING_SIMPLE) == 0) {
					ps.setString(cont, val[0]);
				} else if (val[1].compareTo(DataBaseDictionary.STRING_JOKER) == 0) {
					ps.setString(cont, val[0] + "%");
				} else if (val[1]
						.compareTo(DataBaseDictionary.STRING_DOBLE_JOKER) == 0) {
					ps.setString(cont, "%" + val[0] + "%");
				} else if (val[1].compareTo(DataBaseDictionary.INTEGER_TYPE) == 0) {
					// Cuando el valor es entero
					ps.setInt(cont, Integer.parseInt(val[0]));
				}
				cont++;
			}
			return ps;
		} catch (SQLException ex) {
			// TODO: handle exception
			log.log(Level.SEVERE, null, ex);
		}
		return null;
	}


	@Override
	public Boolean delete(LugarAgregado lugarAgregado) throws DBException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Lugar insert(LugarAgregado lugarAgregado) throws DBException {
		// TODO Auto-generated method stub
		try{
			// Establece la conexion
			Connection c = this.getConnection();
			Integer idLugar = 0;
			LugarDB lugarDB = new LugarDB();
			lugarDB.insert(lugarAgregado.getLugar());
			
			//Se verifica que la solicitud no haya sido creada previamente o no exista una relacion de amistad previa
            PreparedStatement ps = c.prepareStatement(DataBaseDictionary.GET_LAST_LUGAR);
            ResultSet res = this.ejecutarQuery(ps);
            while(res.next()){
            	idLugar = res.getInt("ide_lug");
            }
            log.log(Level.INFO,"ID LUGAR INS = "+idLugar);
            if(idLugar != 0){
            	lugarAgregado.getLugar().setId(idLugar);
				//Si no, se procede a insertar el lugar Agregado
		        ps = c.prepareStatement(DataBaseDictionary.INSERT_LUGAR_AGREGADO);
		        /*
		         * Se insertan los parametros al insert
		         *  [1] = Fecha en que se agrego el lugar
		         *  [2] = ID de la persona que lo agrega
		         *  [3] = ID del lugar a agregar
		         */
		        
				ps.setString(1, lugarAgregado.getFecha());
				ps.setInt(2, lugarAgregado.getPersona().getId());
				ps.setInt(3, idLugar);

				// Se realiza la consulta
				this.ejecutarInstruccion(ps);
				// Procesamiento de resultados
				c.close();
				return lugarAgregado.getLugar();
			} else {
				throw new DBException("ERROR AL INSERTAR");
			}
		} catch (SQLException ex) {
			log.log(Level.SEVERE, null, ex);
			throw new DBException("Error al ejecutar la consulta:\n"
					+ ex.getMessage(), ex);
		}
	}

}
